﻿#include "mserver.h"
#include "mconnectiongroup.h"
#include <QThread>
#include <QTcpServer>
#include <QTimer>

class MServerPrivate
{
public:
    MServerPrivate() {
        curGroup = NULL;
        onlineCount = 0;
    }
public:
    MTcpServer *tcpServer;
    QList<MConnectionGroup *> groupList;
    MConnectionGroup *curGroup;
    QList<QThread*> threads;
    quint32 onlineCount;
};

MServer::MServer(QObject *parent) : QObject(parent)
{
    if (!QMetaType::isRegistered(QMetaType::type("qintptr")))
        qRegisterMetaType<qintptr>("qintptr");
    
    d = new MServerPrivate;
    d->tcpServer = new MTcpServer(this);
    QTimer::singleShot(100,this,SLOT(initReady()));
}

MServer::~MServer()
{
    d->tcpServer->close();
    
    foreach(QThread *thread,d->threads)
    {
        thread->exit();
        thread->wait();
    }
    delete d;
}

void MServer::initReady()
{
    connectionSwitch();
    d->tcpServer->listen(QHostAddress::Any, 6667);
}

void MServer::connectionSwitch(qintptr sktDescriptor)
{
    //断开当前新链接请求处理
    if( d->curGroup )
        disconnect(d->tcpServer,SIGNAL(newIncomingConnection(qintptr)),d->curGroup,SLOT(addNewConnect(qintptr)));
    
    //====构建新的管理组====
    d->curGroup = new MConnectionGroup(sktDescriptor,nullptr);
    d->groupList.append(d->curGroup);
    
    //建立新的新链接请求处理
    connect(d->tcpServer,SIGNAL(newIncomingConnection(qintptr)),d->curGroup,SLOT(addNewConnect(qintptr)));
    //当前客户端满员时
    connect(d->curGroup,SIGNAL(connectionFull(qintptr)),this,SLOT(connectionSwitch(qintptr)));
    connect(d->curGroup,SIGNAL(onlineChange(bool)),this,SLOT(onlineCountChange(bool)));
    
    QThread *thread = new QThread(this);
    d->threads.append(thread);
    
    connect(thread,SIGNAL(started()),d->curGroup,SLOT(startInit()));
    connect(d->curGroup,SIGNAL(releaseSpace()),this,SLOT(groupReleaseSpace()));
    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
    connect(thread, SIGNAL(finished()), d->curGroup, SLOT(deleteLater()));
    
    d->curGroup->moveToThread(thread);
    thread->start();
}

void MServer::groupReleaseSpace()
{
    MConnectionGroup *rGroup = qobject_cast<MConnectionGroup*>(sender());
    for(int i=0;i<d->groupList.count();i++)
    {
        if( d->groupList.at(i) == rGroup ){
            d->groupList.removeAt(i);
            break;
        }
    }
    
    if( rGroup == d->curGroup )
        connectionSwitch();
     
    //释放线程
    QThread *groupThread = rGroup->thread();
    for(int i=0;i<d->threads.count();i++)
    {
        if( d->threads.at(i) == groupThread ){
            d->threads.removeAt(i);
            break;
        }
    }
    
    groupThread->exit();
    groupThread->wait();
    
}

void MServer::onlineCountChange(bool isAdd)
{
    d->onlineCount += isAdd ? 1 : -1;
    if( d->onlineCount < 0 )
        d->onlineCount = 0;
}


//================
MTcpServer::MTcpServer(QObject *parent)
    : QTcpServer(parent)
{
    
}

MTcpServer::~MTcpServer()
{
    
}

void MTcpServer::incomingConnection(qintptr sktDescriptor)
{
    qWarning()<<"----incomingConnection-----"<<sktDescriptor;
    emit newIncomingConnection(sktDescriptor);
}
